package com.gege;

import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition 使用时需要注意：在调用方法前获取锁
 *
 * @author gechenpeng
 * @date 2021-04-13
 */
public class Demo7 {

    public static void main(String[] args) throws Exception {

        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();

        ExecutorService executorService = new ThreadPoolExecutor(5, 5,
                1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(1024),
                new ThreadPoolExecutor.CallerRunsPolicy());

        long start = System.currentTimeMillis();

        // ① 主线程先获取锁
        lock.lock();

        // ② 提交任务异步执行
        Future<String> future = executorService.submit(() -> {
            // ④ 异步线程获取锁
            lock.lock();
            try {
                // ⑤ 执行相关业务代码
                return execute();
            } finally {
                // ⑥ 唤醒所有等待在 Condition 上的线程
                condition.signalAll();
                // ⑦ 释放锁
                lock.unlock();
            }
        });

        // ③ 主线程释放锁，在此等待  ->  ⑧ 主线程重新获取到锁，并从 await() 方法返回
        condition.await();

        // ⑨ 主线程释放锁
        lock.unlock();

        executorService.shutdown();

        String message = future.get();

        System.out.println("线程运行的结果是: " + message + ", 耗时: " +
                (System.currentTimeMillis() - start) + " ms");
    }

    private static String execute() throws Exception {
        Thread.sleep(5000);
        return "ok";
    }
}
